<template>
    <div>
      <!--修改页-->
      <el-form v-if="displayType==='edit'" label-width="95px" class="infoInput" :rules="rules" :model="roleinfo" ref="editForm">
          <el-row>
              <el-col :span="12">
                <el-form-item label="角色名称" prop="roleName">
                    <el-input v-model="roleinfo.roleName" size="medium"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item prop="roleCode">
                  <span slot="label">
                     <span class="span-box">
                       <el-tooltip style="diaplay:inline" effect="dark" content="角色的唯一标识象征着角色对应权限，由英文字符组成" placement="top">
                          <i class="el-icon-question" />
                        </el-tooltip>
                       <span>角色标识</span>
                     </span>
                   </span>
                    <el-input v-model="roleinfo.roleCode" size="medium"></el-input>
                </el-form-item>
              </el-col>
          </el-row>
          <el-row>
              <el-col :span="12">
                <el-form-item label="显示顺序" prop="orderNum">
                    <span slot="label">
                      <span class="span-box">
                        <el-tooltip style="diaplay:inline" effect="dark" content="控制该角色在角色列表的显示顺序，范围在1-100间" placement="top">
                            <i class="el-icon-question" />
                          </el-tooltip>
                        <span>显示顺序</span>
                      </span>
                    </span>
                    <el-input-number v-model="roleinfo.orderNum" controls-position="right" :min="1" :max="100"></el-input-number>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="角色状态">
                    <el-radio v-model="roleinfo.status" label="启用">启用</el-radio>
                    <el-radio v-model="roleinfo.status" label="停用">停用</el-radio>
                </el-form-item>
              </el-col>
          </el-row>
          <el-row>
              <el-col :span="24">
                  <el-form-item label="菜单权限">
                        <el-checkbox @change="expand()">展开/折叠</el-checkbox>
                        <el-checkbox @change="checkAllOrNot()">全选/全不选</el-checkbox>
                        <el-tree ref="tree" :data="menuTree" show-checkbox node-key="id" class="tree-line" icon-class="el-icon-circle-plus-outline"
                        :indent="0" :default-expanded-keys="roleinfo.menuIdList" :default-checked-keys="roleinfo.menuIdList" :props="defaultProps">
                        </el-tree>
                  </el-form-item>
              </el-col>
          </el-row>
          <el-row>
              <el-col>
                  <div class="inlineBtn">
                      <el-button type="primary" size="medium" @click="updateSubmit">提交</el-button>
                      <el-button size="medium" @click="noUpdate">关 闭</el-button>
                  </div>
              </el-col>
          </el-row>
      </el-form>
      <!--新增页-->
      <el-form v-if="displayType==='add'" label-width="95px" class="infoInput" :rules="rules" :model="newrole" ref="addForm">
          <el-row :span="24">
              <el-col :span="12">
                <el-form-item label="角色名称" prop="roleName">
                    <el-input v-model="newrole.roleName" size="medium"></el-input>
                </el-form-item>
              </el-col>

              <el-col :span="12">
                <el-form-item prop="roleCode">
                  <span slot="label">
                     <span class="span-box">
                       <el-tooltip style="diaplay:inline" effect="dark" content="角色的唯一标识象征着角色对应权限，由英文字符组成" placement="top">
                          <i class="el-icon-question" />
                        </el-tooltip>
                       <span>角色标识</span>
                     </span>
                   </span>
                    <el-input v-model="newrole.roleCode" size="medium"></el-input>
                </el-form-item>
              </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
                <el-form-item label="显示顺序" prop="orderNum">
                    <el-input-number v-model="newrole.orderNum" controls-position="right" :min="1" :max="100"></el-input-number>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="角色状态">
                    <el-radio v-model="newrole.status" label="启用">启用</el-radio>
                    <el-radio v-model="newrole.status" label="停用">停用</el-radio>
                </el-form-item>
              </el-col>
          </el-row>
          <el-row>
              <el-col :span="24">
                  <el-form-item label="菜单权限">
                        <el-checkbox @change="expand()">展开/折叠</el-checkbox>
                        <el-checkbox @change="checkAllOrNot()">全选/全不选</el-checkbox>
                        <el-tree ref="tree" :data="menuTree" show-checkbox node-key="id" class="tree-line" icon-class="el-icon-circle-plus-outline"
                        :indent="0" :default-expanded-keys="newrole.menuIdList" :default-checked-keys="newrole.menuIdList" :props="defaultProps">
                        </el-tree>
                  </el-form-item>
              </el-col>
          </el-row>
           <el-row>
              <el-col>
                  <div class="inlineBtn">
                      <el-button type="primary" @click="addSubmit">提交</el-button>
                      <el-button @click="noUpdate">关 闭</el-button>
                  </div>
              </el-col>
          </el-row>
      </el-form>
    </div>
</template>

<script>
export default {
    data(){
        //菜单名深度校验规则
        var validateRoleName = (rule, value, callback) => {
            //中文校验
            const cnReg=/[^u4e00-u9fa5]/; // eslint-disable-line
            if(!cnReg.test(value)){
                callback(new Error('角色名称必须由中文组成'));
            }else{
                callback();
            }
        };
        //菜单名深度校验规则
        var validateCode = (rule, value, callback) => {
            //英文和数字校验
            const reg=/^[A-Za-z0-9]+$/  // eslint-disable-line
            if(!reg.test(value)){
                callback(new Error('角色标识必须由英文和数字组成'));
            }else if(this.roleCodeList.includes(value)){
                callback(new Error('角色标识与已存在的角色标识重复'));
            }else{
              callback();
            }
        };
        return{
            menuTree:[],
            roleinfo:JSON.parse(this.role),//当前操作的角色对象
            newrole:{
              orderNum:1,
              status:"启用"
            },
            //树结构转一维数组
            menuList:[],
            //表单校验规则
            rules:{
                roleName: [
                    { required: true, message: '请输入角色名', trigger: 'blur' },
                    { min: 2, max: 8, message: '长度在 2 到 8 个字符', trigger: 'blur' },
                    { validator: validateRoleName, trigger: 'blur'}
                ],
                roleCode:[
                    { required: true, message: '请输入角色标识', trigger: 'blur' },
                    { min: 2, max: 12, message: '长度在 2 到 12 个字符', trigger: 'blur' },
                    { validator: validateCode, trigger: 'blur'}
                ],
                orderNum: [
                    { required: true, message: '请设置菜单显示顺序', trigger: 'change' }
                ],
            },
            roleCodeList:[],//已存在的角色标识
            childMenuList:[],
            checked:false,//是否选中
            isExpand:false,//是否展开
            defaultProps: {//树配置信息
                children: 'children',
                label: 'menuName'
            }
        }
    },
    props:['role','displayType'],
    methods:{
        //修改提交
        updateSubmit(){
          if(!this.checkForm('editForm')){
                return
          }
          //console.log(this.roleinfo);
          //console.log(this.$refs.tree.getCheckedKeys());
          let menuIdList=this.$refs.tree.getCheckedKeys();
          let roleinfo=this.roleinfo
          roleinfo=this.sa.displaceIntStatus(this.roleinfo)
          menuIdList=menuIdList.filter((menuId)=>{
            return !this.childMenuList.includes(menuId)
          })
          const map={"roleinfo":roleinfo,"menuIdList":menuIdList}
          let params=map
          console.log(params);
          this.requestJsonMap('/api/role/update',params,{'Content-Type': 'application/json'}).then(res=>{
            if(!res){return}
            this.$bus.$emit("updateRoleCallBack")
          })
        },
        //新增提交
        addSubmit(){
          if(!this.checkForm('addForm')){
                return
          }
          console.log(this.newrole);
          //console.log(this.$refs.tree.getCheckedKeys());
          let menuIdList=this.$refs.tree.getCheckedKeys();
          menuIdList=menuIdList.filter((menuId)=>{
            return !this.childMenuList.includes(menuId)
          })
          let newrole=this.sa.displaceIntStatus(this.newrole)
          const map={"roleinfo":newrole,"menuIdList":menuIdList}
          let params=map
          console.log(params);
          this.requestJsonMap('/api/role/add',params,{'Content-Type': 'application/json'}).then(res=>{
            if(!res){return}
            this.$bus.$emit("addRoleCallBack")
          })
        },
        //表单提交前置校验
        checkForm(formName){
            let flag;
            this.$refs[formName].validate((valid) => {
                if (valid) {
                    flag=true;
                    return true;
                } else {
                    flag=false
                    return false;
                }
            });
            return flag
        },
        //取消修改
        noUpdate(){
            this.$bus.$emit("noUpdate")
        },
         //展开/折叠
        expand() {
          //这里是真有鬼，复选框v-model绑定this.isExpand，展开后再次点击不起作用，换用button直接取反可以
          //后决定仍用复选框，但是v-model不绑定属性，自己取反
          this.isExpand=!this.isExpand
          const nodes = this.$refs.tree.store._getAllNodes()
          for (let i in nodes) {
            nodes[i].expanded = this.isExpand
          }
        },
        //全选/全不选
        checkAllOrNot() { 
          //同上
          this.checked=!this.checked
          if(this.checked){
            this.$refs.tree.setCheckedNodes(this.menuTree)
          }else{
            this.$refs.tree.setCheckedKeys([])
          }

        },
    },
    created(){
      //获取角色对应的菜单权限
        let params=this.roleinfo.id;
        this.request('/api/role/getMenuByRole?id='+params).then(res=>{
          if(!res){return}
          this.roleinfo.menuIdList=res.data
        })
    },
    mounted(){
        //获取菜单树
        this.request('/api/menu/getMenuTree',params).then(res=>{
          if(!res){return}
          this.menuTree=res.data;
        })
        
        //获取角色对应的菜单权限
        let params=this.roleinfo.id;
        this.request('/api/role/getMenuByRole?id='+params).then(res=>{
          if(!res){return}
          this.roleinfo.menuIdList=res.data
        })

        //获取已存在的角色标识，做唯一校验
        this.request('/api/role/getAllRoleCode').then(res=>{
          if(!res){return}
          this.roleCodeList=res.data
          //如果是修改页，移除原本的权限标识，防止没改标识还会报重复（因为原标识已存在数据库中了
          if(this.displayType==="edit"){
            let index=this.roleCodeList.indexOf(this.roleinfo.roleCode);
            this.roleCodeList.splice(index,index+1);
            //console.log(this.roleCodeList);
          }
        })

        this.request('/api/menu/queryChildMenuId').then(res=>{
          if(!res){return}
          this.childMenuList=res.data
          console.log(this.childMenuList);
        })
    }
}
</script>

<style lang="scss">
/*修改页按钮 */
.inlineBtn {
    text-align:center
}
/*表单input框样式控制 */
.infoInput >div>div>div>div>div>input{
  width:90%;
}
/*树结构 */
.tree-line{
  .el-tree-node {
    position: relative;
    padding-left: 16px; // 缩进量
  }
  .el-tree-node__children {
    padding-left: 16px; // 缩进量
  }

  // 竖线
  .el-tree-node::before {
    content: "";
    height: 100%;
    width: 1px;
    position: absolute;
    left: -3px;
    top: -26px;
    border-width: 1px;
    border-left: 1px dashed #52627C;
  }
  // 当前层最后一个节点的竖线高度固定
  .el-tree-node:last-child::before {
    height: 38px; // 可以自己调节到合适数值
  }

  // 横线
  .el-tree-node::after {
    content: "";
    width: 24px;
    height: 20px;
    position: absolute;
    left: -3px;
    top: 12px;
    border-width: 1px;
    border-top: 1px dashed #52627C;
  }

  // 去掉最顶层的虚线，放最下面样式才不会被上面的覆盖了
  & > .el-tree-node::after {
    border-top: none;
  }
  & > .el-tree-node::before {
    border-left: none;
  }
	
  // 展开关闭的icon
  .el-tree-node__expand-icon{
    font-size: 16px;
    // 叶子节点（无子节点）
    &.is-leaf{
      color: transparent;
      // display: none; // 也可以去掉
    }
  }
}
</style>